﻿using System;
using Sinacor.Infra.UI.Common;
using System.Linq;

namespace Sinacor.UI.Bovespa.Contabil.Presenter
{
    /// <summary>
    /// Presenter Class - CadastroContaContabilFaturamento
    /// </summary>
    public class CadastroContaContabilFaturamento : BasePresenter<ICadastroContaContabilFaturamento>
    {
        #region Atributos

        private Communication.ContaContabilFaturamento _communicationContaContabilFaturamento;
        private Communication.ContaContabil _communicationContaContabil;
        private Communication.Negocio _communicationNegocio;
        private Communication.Municipio _communicationMunicipio;
        private Communication.EventoContabil _communicationEventoContabil;
        private Communication.GrupoContabil _communicationGrupoContabil;
        private bool _contabilidadeInstalado;

        #endregion

        #region Models

        public Model.Parameter.FiltroContaContabilFaturamento FiltroContasContabeis
        {
            get;
            set;
        }

        public ModelCollection<Model.Bolsa> ListaBolsas
        {
            get;
            private set;
        }

        public ModelCollection<Model.Municipio> ListaMunicipios
        {
            get;
            private set;
        }

        public ModelCollection<Model.EventoContabil> ListaEventosContabeis
        {
            get;
            private set;
        }

        public ModelCollection<Model.GrupoContabil> ListaGruposContabeis
        {
            get;
            private set;
        }

        public ModelCollection<Model.ContaContabilFaturamento> ListaContasContabeis
        {
            get;
            private set;
        }

        #endregion

        #region Construtor

        /// <summary>
        /// Construtor
        /// </summary>
        /// <param name="view">ICadastroContaContabilFaturamento</param>
        public CadastroContaContabilFaturamento(ICadastroContaContabilFaturamento CadastroContaContabilFaturamento)
            : base(CadastroContaContabilFaturamento)
        {
            this._communicationContaContabilFaturamento = new Communication.ContaContabilFaturamento(this.Session);
            this._communicationContaContabil = new Communication.ContaContabil(this.Session);
            this._communicationNegocio = new Communication.Negocio(this.Session);
            this._communicationMunicipio = new Communication.Municipio(this.Session);
            this._communicationEventoContabil = new Communication.EventoContabil(this.Session);
            this._communicationGrupoContabil = new Communication.GrupoContabil(this.Session);
        }

        #endregion

        #region Métodos Privados

        #region ConsultarBolsas

        private void ConsultarBolsas()
        {
            try
            {
                this.ListaBolsas = this._communicationNegocio.ConsultarBolsas();
                this.View.AtualizarBolsas();
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }
        }

        #endregion

        #region ConsultarMunicipios

        private void ConsultarMunicipios()
        {
            try
            {
                this.ListaMunicipios = this._communicationMunicipio.ConsultarMunicipios();
                this.View.AtualizarMunicipios();
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }

        }

        #endregion

        #region ConsultarEventosContabeis

        private void ConsultarEventosContabeis()
        {
            try
            {
                this.ListaEventosContabeis = this._communicationEventoContabil.ConsultarEventosContabeis
                    (
                        new Sinacor.UI.Bovespa.Contabil.Model.Parameter.FiltroEventoContabil() { Codigo = null, Descricao = null }
                    );

                this.View.AtualizarEventosContabeis();
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }

        }

        #endregion

        #region ConsultarGruposContabeis

        private void ConsultarGruposContabeis()
        {
            try
            {
                this.ListaGruposContabeis = this._communicationGrupoContabil.ConsultarGruposContabeis();
                this.View.AtualizarGruposContabeis();
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }
        }

        #endregion

        #region ConsultarContasContabeisFaturamento

        private void ConsultarContasContabeisFaturamento()
        {
            try
            {
                this.ListaContasContabeis = this._communicationContaContabilFaturamento.ConsultarContasContabeisFaturamento(this.FiltroContasContabeis);

                this.View.AtualizarContasContabeisFaturamento();
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }
        }

        #endregion

        #region ValidarContaContabilFaturamento

        private Boolean ValidarContaContabilFaturamento(Model.ContaContabilFaturamento parameter)
        {
            try
            {
                Model.EventoContabil eventoContabil = this.ListaEventosContabeis.FirstOrDefault(x => x.Codigo == parameter.CodigoEventoContabil);

                if (eventoContabil.UtilizaMunicipio.Value && !parameter.CodigoMunicipio.HasValue)
                {
                    this.View.InformarMunicipioObrigatorio();
                    return false;
                }

                if (!parameter.CodigoHistoricoCredito.HasValue)
                {
                    this.View.InformarCodigoHistoricoCreditoObrigatorio();
                    return false;
                }

                if (!parameter.CodigoHistoricoDebito.HasValue)
                {
                    this.View.InformarCodigoHistoricoDebitoObrigatorio();
                    return false;
                }

                if (!parameter.CodigoHistoricoEstorno.HasValue)
                {
                    this.View.InformarCodigoHistoricoEstornoObrigatorio();
                    return false;
                }

                if (!(parameter.CodigoResumidoCredito.HasValue && parameter.DigitoResumidoCredito.HasValue) || String.IsNullOrEmpty(parameter.ContaCredito))
                {
                    this.View.InformarCodigoResumidoContaCredito();
                    return false;
                }

                if (!(parameter.CodigoResumidoDebito.HasValue && parameter.DigitoResumidoDebito.HasValue) || String.IsNullOrEmpty(parameter.ContaDebito))
                {
                    this.View.InformarCodigoResumidoContaDebito();
                    return false;
                }

                return true;
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
                return false;
            }
        }

        #endregion

        #region VerificarModuloContabilidadeInstalado

        private Boolean VerificarModuloContabilidadeInstalado()
        {
            return _contabilidadeInstalado;
        }

        #endregion

        #region CarregarContaDebitoPorContaDebito

        private void CarregarContaDebitoPorContaDebito(Model.ContaContabilFaturamento request)
        {
            if (!String.IsNullOrEmpty(request.ContaDebito))
            {
                if (this.VerificarModuloContabilidadeInstalado())
                {
                    if (!request.CodigoResumidoDebito.HasValue && !request.DigitoResumidoDebito.HasValue)
                    {
                        ModelCollection<Model.PlanoConta> planoConta = ConsultarPlanosContas(new Model.Parameter.FiltroPlanoConta()
                        {
                            CodigoConta = request.ContaDebito,
                            CodigoResumidoConta = request.CodigoResumidoDebito,
                            DigitoResumidoConta = request.DigitoResumidoDebito
                        });

                        if (planoConta.Count > 0)
                            this.View.InformarDadosContaDebitoPorContaDebito(planoConta[0].CodigoResumidoConta, planoConta[0].DigitoResumidoConta, planoConta[0].NomeConta);
                        else
                            this.View.InformarDadosContaDebitoPorContaDebito(request.CodigoResumidoDebito, request.DigitoResumidoDebito, null);
                    }
                }
            }
        }

        #endregion

        #region CarregarContaDebitoPorDigitoResumido

        private void CarregarContaDebitoPorDigitoResumido(Model.ContaContabilFaturamento request)
        {
            if (request.DigitoResumidoDebito.HasValue)
            {
                if (this.VerificarModuloContabilidadeInstalado())
                {
                    if (request.CodigoResumidoDebito.HasValue && request.DigitoResumidoDebito.HasValue)
                    {
                        ModelCollection<Model.PlanoConta> planoConta = ConsultarPlanosContas(new Model.Parameter.FiltroPlanoConta()
                        {
                            CodigoResumidoConta = request.CodigoResumidoDebito,
                            DigitoResumidoConta = request.DigitoResumidoDebito
                        });

                        if (planoConta.Count > 0)
                            this.View.InformarDadosContaDebitoPorDigitoResumido(planoConta[0].CodigoConta, planoConta[0].DigitoResumidoConta, planoConta[0].NomeConta);
                        else
                            this.View.InformarDadosContaDebitoPorDigitoResumido(request.ContaDebito, request.DigitoResumidoDebito.Value, null);
                    }
                }
            }
        }

        #endregion

        #region CarregarContaCreditoPorContaCredito

        private void CarregarContaCreditoPorContaCredito(Model.ContaContabilFaturamento request)
        {
            if (!String.IsNullOrEmpty(request.ContaCredito))
            {
                if (this.VerificarModuloContabilidadeInstalado())
                {
                    if (!request.CodigoResumidoCredito.HasValue && !request.DigitoResumidoCredito.HasValue)
                    {
                        ModelCollection<Model.PlanoConta> planoConta = ConsultarPlanosContas(new Model.Parameter.FiltroPlanoConta()
                        {
                            CodigoConta = request.ContaCredito,
                            CodigoResumidoConta = request.CodigoResumidoCredito,
                            DigitoResumidoConta = request.DigitoResumidoCredito
                        });

                        if (planoConta != null && planoConta.Count > 0)
                            this.View.InformarDadosContaCreditoPorContaCredito(planoConta[0].CodigoResumidoConta, planoConta[0].DigitoResumidoConta, planoConta[0].NomeConta);
                        else
                            this.View.InformarDadosContaCreditoPorContaCredito(request.CodigoResumidoCredito, request.DigitoResumidoCredito, null);
                    }
                }
            }
        }

        #endregion

        #region CarregarContaCreditoPorDigitoResumido

        private void CarregarContaCreditoPorDigitoResumido(Model.ContaContabilFaturamento request)
        {
            if (request.DigitoResumidoCredito.HasValue)
            {
                if (this.VerificarModuloContabilidadeInstalado())
                {
                    if (request.CodigoResumidoCredito.HasValue)
                    {
                        ModelCollection<Model.PlanoConta> planoConta = ConsultarPlanosContas(new Model.Parameter.FiltroPlanoConta()
                                                                                             {
                                                                                                 CodigoResumidoConta = request.CodigoResumidoCredito,
                                                                                                 DigitoResumidoConta = request.DigitoResumidoCredito
                                                                                             }
                                                                                             );

                        if (planoConta.Count > 0)
                            this.View.InformarDadosContaCreditoPorDigitoResumido(planoConta[0].CodigoConta, planoConta[0].DigitoResumidoConta, planoConta[0].NomeConta);
                        else
                            this.View.InformarDadosContaCreditoPorDigitoResumido(request.ContaCredito, request.DigitoResumidoCredito.Value, null);
                    }
                }
            }
        }

        #endregion

        #endregion

        #region Métodos Públicos

        #region Inicializar

        /// <summary>
        /// Inicializar
        /// </summary>
        public void Inicializar()
        {
            try
            {
                this.ConsultarBolsas();
                this.ConsultarGruposContabeis();
                this.ConsultarEventosContabeis();
                this.ConsultarMunicipios();

                this.FiltroContasContabeis = new Model.Parameter.FiltroContaContabilFaturamento()
                                               {
                                                   CodigoBolsa = null,
                                                   CodigoEventoContabil = null,
                                                   CodigoGrupoContabil = null,
                                                   CodigoMunicipio = null
                                               };

                this.ConsultarContasContabeisFaturamento();
                _contabilidadeInstalado = (new Sinacor.UI.Bovespa.Contabil.Communication.Acesso(this.Session)).VerificarSistemaInstalado("CTB");
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }
        }

        #endregion

        #region CarregarContaCredito

        /// <summary>
        /// Carrega Conta Crédito
        /// </summary>
        /// <param name="contaContabil">Model.ContaContabilFaturamento</param>
        /// <param name="tipoPesquisa">Model.Enum.TipoPesquisaConta</param>
        public void CarregarContaCredito(Model.ContaContabilFaturamento contaContabil, Model.Enum.TipoPesquisaConta tipoPesquisa)
        {
            if (tipoPesquisa == Model.Enum.TipoPesquisaConta.Conta)
                CarregarContaCreditoPorContaCredito(contaContabil);
            else if (tipoPesquisa == Model.Enum.TipoPesquisaConta.DigitoResumido)
            {
                CarregarContaCreditoPorDigitoResumido(contaContabil);
            }
        }

        #endregion

        #region CarregarContaDebito

        /// <summary>
        /// Carrega Conta Débito
        /// </summary>
        /// <param name="contaContabil">Model.ContaContabilFaturamento</param>
        /// <param name="tipoPesquisa">Model.Enum.TipoPesquisaConta</param>
        public void CarregarContaDebito(Model.ContaContabilFaturamento contaContabil, Model.Enum.TipoPesquisaConta tipoPesquisa)
        {
            if (tipoPesquisa == Model.Enum.TipoPesquisaConta.Conta)
                CarregarContaDebitoPorContaDebito(contaContabil);
            else if (tipoPesquisa == Model.Enum.TipoPesquisaConta.DigitoResumido)
            {
                CarregarContaDebitoPorDigitoResumido(contaContabil);
            }
        }

        #endregion

        #region ConsultarContasContabeis

        /// <summary>
        /// Consulta Contas Contábeis
        /// </summary>
        public void ConsultarContasContabeis()
        {
            try
            {
                this.ListaContasContabeis = this._communicationContaContabilFaturamento.ConsultarContasContabeisFaturamento(this.FiltroContasContabeis);
                this.View.AtualizarContasContabeisFaturamento();
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }
        }

        #endregion

        #region ConsultarPlanosContas

        public ModelCollection<Model.PlanoConta> ConsultarPlanosContas(Model.Parameter.FiltroPlanoConta request)
        {
            return this._communicationContaContabilFaturamento.ConsultarPlanosContas(request);
        }

        #endregion

        #region IncluirContaContabilFaturamento

        public Boolean IncluirContaContabilFaturamento(Model.ContaContabilFaturamento parameter)
        {
            try
            {
                if (this.ValidarContaContabilFaturamento(parameter) && this.ValidarCodigoHistorico(parameter.CodigoHistoricoEstorno, parameter.DigitoHistoricoEstorno, Model.Enum.TipoHistorico.Estorno))
                {
                    this._communicationContaContabilFaturamento.IncluirContaContabilFaturamento(parameter);
                    this.View.InformarContaContabilIncluidaSucesso();
                    return true;
                }
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
                return false;
            }

            return false;
        }

        #endregion

        #region AlterarContaContabilFaturamento

        /// <summary>
        /// Altera Conta Contábil Faturamento
        /// </summary>
        /// <param name="model">Model.ContaContabilFaturamento</param>
        public Boolean AlterarContaContabilFaturamento(Model.ContaContabilFaturamento parameter)
        {
            try
            {
                if (this.ValidarContaContabilFaturamento(parameter) && this.ValidarCodigoHistorico(parameter.CodigoHistoricoEstorno, parameter.DigitoHistoricoEstorno, Model.Enum.TipoHistorico.Estorno))
                {
                    this._communicationContaContabilFaturamento.AlterarContaContabilFaturamento(parameter);
                    this.View.InformarContaContabilAlteradaSucesso();
                    return true;
                }
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
                return false;
            }

            return false;
        }

        #endregion

        #region ExcluirContaContabilFaturamento

        /// <summary>
        /// Exclui Conta Contábil
        /// </summary>
        /// <param name="parameter">Model.ContaContabilFaturamento</param>
        /// <returns>Boolean</returns>
        public Boolean ExcluirContaContabilFaturamento(Model.ContaContabilFaturamento parameter)
        {
            try
            {
                if (parameter == null)
                    this.View.InformarSelecioneContaContabil();

                if (this.View.ConfirmarExclusaoContaContabil())
                {
                    this._communicationContaContabilFaturamento.ExcluirContaContabilFaturamento
                        (
                            new Model.Parameter.FiltroContaContabilFaturamentoChave()
                            {
                                CodigoBolsa = parameter.CodigoBolsa,
                                CodigoEventoContabil = parameter.CodigoEventoContabil,
                                CodigoGrupoContabil = parameter.CodigoGrupoContabil,
                                CodigoMunicipio = parameter.CodigoMunicipio
                            }
                        );

                    this.View.InformarExclusaoSucesso();

                    return true;
                }

                return false;
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
                return false;
            }
        }

        #endregion

        #region ValidarUtilizacaoMunicipio

        /// <summary>
        /// Validar utilização de município
        /// </summary>
        /// <param name="request">Model.EventoContabil</param>
        public void ValidarUtilizacaoMunicipio(Model.EventoContabil request)
        {
            try
            {
                if (request == null || !request.UtilizaMunicipio.HasValue || !request.UtilizaMunicipio.Value)
                    this.View.DesabilitarConfiguracaoMunicipio();
                else
                    this.View.HabilitarConfiguracaoMunicipio();
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }
        }

        #endregion

        #region ValidarCodigoHistorico

        /// <summary>
        /// Validar código histórico
        /// </summary>
        /// <param name="request">Model.EventoContabil</param>
        public bool ValidarCodigoHistorico(int? codigoHistorico, int? digitoHistorico, Model.Enum.TipoHistorico tipoHistorico)
        {
            bool isValido = false;

            try
            {
                if (VerificarModuloContabilidadeInstalado())
                {
                    if (codigoHistorico.HasValue && digitoHistorico.HasValue)
                    {
                        Model.Parameter.FiltroHistoricoContabil filtro = new Model.Parameter.FiltroHistoricoContabil
                        {
                            Codigo = codigoHistorico,
                            Digito = digitoHistorico
                        };

                        ModelCollection<Model.HistoricoContabil> retorno = this._communicationContaContabil.ConsultarHistoricosContabeis(filtro);

                        if (retorno != null && retorno.Count > 0)
                        {
                            isValido = true;
                        }
                        else
                        {
                            switch (tipoHistorico)
                            {
                                case Model.Enum.TipoHistorico.Credito:
                                    this.View.InformarCodigoHistoricoCreditoInvalido();
                                    break;
                                case Model.Enum.TipoHistorico.Debito:
                                    this.View.InformarCodigoHistoricoDebitoInvalido();
                                    break;
                                case Model.Enum.TipoHistorico.Estorno:
                                    this.View.InformarCodigoHistoricoEstornoInvalido();
                                    break;
                            }
                        }
                    }
                    else
                    {
                        switch (tipoHistorico)
                        {
                            case Model.Enum.TipoHistorico.Credito:
                                this.View.InformarCodigoHistoricoCreditoInvalido();
                                break;
                            case Model.Enum.TipoHistorico.Debito:
                                this.View.InformarCodigoHistoricoDebitoInvalido();
                                break;
                            case Model.Enum.TipoHistorico.Estorno:
                                this.View.InformarCodigoHistoricoEstornoInvalido();
                                break;
                        }
                    }
                }
                else
                {
                    isValido = true;
                }
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }

            return isValido;
        }

        #endregion

        #endregion
    }
}
